#include <Precomp.h>
#include <UIManager.h>
#include <SoundManager.h>
#include <AVUIXMLParser.h>
#include <AVUIXamlParser.h>
#include <AVUIButton.h>
#include <AVUITextBlock.h>
#include <AVUIIClientRendererInterface.h>
#include <AVUIDispatcher.h>
#include <AVUIDispatcherTimer.h>
#include <AVUIInputManager.h>
#include <AVUINavigationWindow.h>
#include <AVUITransitioningPage.h>
#include <AVUIUri.h>

using namespace AVUI;

CUIManager::CUIManager(CSoundManager* pSoundManager) : m_pSoundManager(pSoundManager)
{
    Application::get_Current()->set_MainWindow(object_allocate<NavigationWindow>());
    Application::get_Current()->get_MainWindow()->set_WindowState(WindowState::Maximized);
    Application::get_Current()->get_MainWindow()->set_WindowStyle(WindowStyle::None);
    Application::get_Current()->get_MainWindow()->set_ResizeMode(ResizeMode::NoResize);
    Application::get_Current()->get_MainWindow()->Show();

    m_pOKCancelDialog = object_allocate<NavigationWindow>();
    m_pOKCancelDialog->set_WindowState(WindowState::Maximized);
    m_pOKCancelDialog->set_WindowStyle(WindowStyle::None);
    m_pOKCancelDialog->set_ResizeMode(ResizeMode::NoResize);


    m_pOKCancelDialogPage = CUIManager::LoadXamlScene(L"Media\\Xaml\\OkCancelDialog.xaml");

    m_pOKCancelDialog->set_Content(m_pOKCancelDialogPage);

    CUIManager::FindButton(m_pOKCancelDialogPage, L"OkButton")->add_Click(RoutedEventHandler::Create(this, &CUIManager::OnOkClicked));
    CUIManager::FindButton(m_pOKCancelDialogPage, L"CancelButton")->add_Click(RoutedEventHandler::Create(this, &CUIManager::OnCancelClicked));    

    m_pOptionsWindow = object_allocate<NavigationWindow>();
}

CUIManager::~CUIManager()
{
    /*
    m_pOKCancelDialog->Release();
    m_pOKCancelDialog = NULL;
    */
}

void CUIManager::ShowOKDialog(const WCHAR* wzMessage, DialogResultCallback dialogResultCallback)
{
    CUIManager::FindButton(m_pOKCancelDialogPage, L"CancelButton")->set_Visibility(Visibility::Collapsed);
    CUIManager::FindButton(m_pOKCancelDialogPage, L"OkButton")->set_Visibility(Visibility::Visible);

    ShowOkCancelDialogCore(wzMessage, dialogResultCallback);
}

void CUIManager::ShowOKCancelDialog(const WCHAR* wzMessage, DialogResultCallback dialogResultCallback)
{
    CUIManager::FindButton(m_pOKCancelDialogPage, L"CancelButton")->set_Visibility(Visibility::Visible);
    CUIManager::FindButton(m_pOKCancelDialogPage, L"OkButton")->set_Visibility(Visibility::Visible);

    ShowOkCancelDialogCore(wzMessage, dialogResultCallback);
}

void CUIManager::ShowCancelDialog(const WCHAR* wzMessage, DialogResultCallback dialogResultCallback)
{
    CUIManager::FindButton(m_pOKCancelDialogPage, L"CancelButton")->set_Visibility(Visibility::Visible);
    CUIManager::FindButton(m_pOKCancelDialogPage, L"OkButton")->set_Visibility(Visibility::Collapsed);

    ShowOkCancelDialogCore(wzMessage, dialogResultCallback);
}

void CUIManager::ShowOkCancelDialogCore(const WCHAR* wzMessage, DialogResultCallback dialogResultCallback)
{
    m_pDialogResultCallbackHolder = new CDialogResultCallbackHolder(dialogResultCallback);

    CUIManager::FindTextBlock(m_pOKCancelDialogPage, L"NotifyText")->set_Text(object_allocate<String>(wzMessage));

    m_pOKCancelDialog->ShowDialog();

    RoutedEventArgs eventArgs(TransitioningPage::get_TransitionInEvent());
    m_pOKCancelDialogPage->RaiseEvent(&eventArgs);

}

void CUIManager::ShowOptionsWindow()
{
    m_pOptionsWindow->Show();
    m_pOptionsWindow->Navigate(object_allocate<Uri>(_S("Media\\Xaml\\OptionsMenu.xaml")));
}

void CUIManager::EndCurrentDialog(EDialogResult eDialogResult)
{
    Dispatcher::get_CurrentDispatcher()->get_InputManager()->LockInputs();

    RoutedEventArgs eventArgs(TransitioningPage::get_TransitionOutEvent());
    m_pOKCancelDialogPage->RaiseEvent(&eventArgs);

    TRefCountedPtr<DispatcherTimer> pTimer = object_allocate<DispatcherTimer>(TimeSpan::FromMilliseconds(500), EventHandler::Create(this, &CUIManager::EndCurrentDialogPostTransition));

    pTimer->Start();

    m_eDeferredDialogResult = eDialogResult;
}

void CUIManager::EndCurrentDialogPostTransition(AVUI::Object* pSender, AVUI::EventArgs* pArgs)
{
    ((DispatcherTimer*)pSender)->Stop();

    Dispatcher::get_CurrentDispatcher()->get_InputManager()->UnlockInputs();

    if(m_pDialogResultCallbackHolder != NULL)
    {
        CDialogResultCallbackHolder* pDialogResultCallbackHolder = m_pDialogResultCallbackHolder;
        m_pDialogResultCallbackHolder = NULL;

        pDialogResultCallbackHolder->GetDialogResultCallback()(m_eDeferredDialogResult);

        delete pDialogResultCallbackHolder;
    }

    m_pOKCancelDialog->EndDialog();
}


class FileLoader : public AVUI::IXMLParserDataProvider
{
public:
    FileLoader(const WCHAR* wzFileName)
    {
        m_hFile = CreateFileW(wzFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
        if(m_hFile == INVALID_HANDLE_VALUE)
        {
            Sleep(500);
            m_hFile = CreateFileW(wzFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
        }
        
    }

    ~FileLoader()
    {
        CloseHandle(m_hFile);
    }

    virtual void ReadData(unsigned char *pbData, int cbMaxData, int *pcbRead)
    {
        ReadFile(m_hFile, pbData, cbMaxData, (DWORD*) pcbRead, NULL);
    }

    HANDLE m_hFile;
};


AVUI::Object* CUIManager::LoadXaml(const WCHAR* wzXamlFile)
{
    using namespace AVUI;

    XamlParser xamlParser;

    FileLoader fileLoader(wzXamlFile);

    XmlParser xmlParser(&fileLoader, &xamlParser);

    ObjectPtr pObject = NULL;

    xmlParser.Parse();
    pObject = xamlParser.get_RootElement();

    pObject->AddRef();

    return pObject;
}

AVUI::FrameworkElement* CUIManager::LoadXamlScene(const WCHAR* wzXamlFile)
{
    return object_cast<FrameworkElement>(CUIManager::LoadXaml(wzXamlFile));
}

AVUI::ResourceDictionary* CUIManager::LoadXamlResources(const WCHAR* wzXamlFile)
{
    return object_cast<ResourceDictionary>(CUIManager::LoadXaml(wzXamlFile));
}

AVUI::Button* CUIManager::FindButton(AVUI::FrameworkElement* pSceneRoot, const WCHAR* wzButtonName)
{
    return object_cast<AVUI::Button>(pSceneRoot->FindName(object_allocate<String>(wzButtonName)));
}

AVUI::TextBlock* CUIManager::FindTextBlock(AVUI::FrameworkElement* pSceneRoot, const WCHAR* wzTextBlockName)
{
    return object_cast<AVUI::TextBlock>(pSceneRoot->FindName(object_allocate<String>(wzTextBlockName)));
}

AVUI::TextBox* CUIManager::FindTextBox(AVUI::FrameworkElement* pSceneRoot, const WCHAR* wzTextBoxName)
{
    return object_cast<AVUI::TextBox>(pSceneRoot->FindName(object_allocate<String>(wzTextBoxName)));
}

void CUIManager::OnOkClicked(AVUI::Object* pObject, AVUI::RoutedEventArgs* pArgs)
{
    EndCurrentDialog(eDialogResult_OK);
}
void CUIManager::OnCancelClicked(AVUI::Object* pObject, AVUI::RoutedEventArgs* pArgs)
{
    EndCurrentDialog(eDialogResult_Cancel);
}

                                                    
